package org.gnomus.server.controllers;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Transaction;
import org.gnomus.data.item;
import org.gnomus.data.lesson;
import org.gnomus.data.link;
import org.gnomus.data.store;
import org.gnomus.server.Context;
import org.gnomus.server.Controller;
import org.gnomus.util.strings;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class Admin implements Controller {
    public String json;
    public String id;
    public String title;
    public String subject;
    public String order;
    public String type;
    public String kind;
    public String property_name;
    public String property_value;

    public boolean index() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        List<Map> lessons = new ArrayList<Map>();
        for (Entity e : store.get("lesson")) {
            lessons.add(new lesson(e));
        }
        ctx.data.put("lessons", lessons);
        return isAdmin();
    }

    public boolean createLesson() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        if ("POST".equals(ctx.method) && title != null && subject != null) {
            lesson lsn  = new lesson(title, subject);
            lsn.save();
            ctx.redirect("/admin/edit_lesson?id=" + lsn.getId());
            return false;
        }
        ctx.redirect("/admin");
        return true;
    }

    public boolean editLesson() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        ctx.data.put("lesson", lesson.fetch(id));
        ctx.js.add("lesson");
        ctx.js.add("item");
        ctx.js.add("task/build_atom");
        ctx.js.add("graphics/atomic_models");
        ctx.js.add("graphics/electric_charge");
        ctx.js.add("tiny_mce/tiny_mce");
        ctx.css.add("lesson");
        return true;
    }

    public boolean importLesson() {
/*
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        if ("POST".equals(ctx.method) && json != null) {
            Transaction txn = store.beginTransaction();
            try {
                JSONObject jo = new JSONObject(json);
                lesson lsn = new lesson(jo);
                JSONArray ja = jo.getJSONArray("items");
                List<item> items = new ArrayList();
                for (int i = 0; i < ja.length(); i++) {
                    items.add(new item(ja.getJSONObject(i)));
                }
                lsn.save();
                for (item itm : items) {
                    itm.save();
                    link lnk = new link("lesson", lsn.key, "item", itm.key);
                    lnk.save();
                }
                txn.commit();
            } catch (JSONException e) {
                throw new Error(e);
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
                ctx.redirect("/admin");
            }
        }
*/
        return true;
    }

    public boolean exportLesson() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();

        lesson lsn = lesson.fetch(id);
        lsn.remove("id");
        lsn.remove("created");
        for (item itm : lsn.getItems()) {
            itm.remove("id");
            itm.remove("created");
        }
        ctx.json = lsn;
        return true;
    }

    public boolean createItem() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        if (!"POST".equals(ctx.method) || id == null || title == null || type == null || order == null) {
            return false;
        }
        lesson lsn = lesson.fetch(id);
        List<item> items = lsn.getItems();
        for (item i : items) {
            if (strings.simplify(title).equals(strings.simplify(i.getTitle()))) {
                ctx.redirect("/admin/edit_lesson?id=" + id);
                return false;
            }
        }
        item itm = new item(title, type, order);
        Transaction txn = store.beginTransaction();
        try {
            itm.save();
            link lnk = new link("lesson", lsn.key, "item", itm.key);
            lnk.save();
            txn.commit();
        } finally {
            if (txn.isActive()) {
                txn.rollback();
            }
        }
        ctx.redirect("/admin/edit_lesson?id=" + lsn.getId());
        return false;
    }

    public boolean editObject() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        ctx.ajax = true;
        if (!"POST".equals(ctx.method) || kind == null || id == null
                || property_name == null || property_value == null) {
            return false;
        }
        Entity e = store.get(kind, id);
        store.setProperty(e, property_name, property_value);
        store.put(e);

        return false;
    }

    public boolean deleteObject() {
        if (!isAdmin()) { return false; }

        Context ctx = Context.get();
        ctx.ajax = true;
        if (!"POST".equals(ctx.method) || kind == null || id == null ) { return false; }
        Entity e = store.get(kind, id);
        Transaction txn = store.beginTransaction();
        try {
            if ("lesson".equals(kind)) {
                new lesson(e).delete();
            } else if ("item".equals(kind)) {
                new item(e).delete();
            }
            txn.commit();
        } finally {
            if (txn.isActive()) {
                txn.rollback();
            }
        }
        store.delete(e);
        return false;
    }

    private boolean isAdmin() {
        Context ctx = Context.get();
        if (!ctx.admin) {
            ctx.redirect(ctx.account != null ? "/" : Context.us.createLoginURL(ctx.uri));
        }
        return ctx.admin;
    }
}
